import Router from 'koa-router'
import { Article, Order } from '../../service'
import CONFIG from '../../config'
import request from 'request'

const crypto = require('crypto');
const xml2json = require('fast-xml-parser');
const json2xml = new xml2json.j2xParser()
const router = new Router();

router.get('/', async(ctx)=>{
    let data = null
    if(ctx.query.id){//根据ID查询
        data = await Article.get(ctx.query.id)
    }
    if(!data && ctx.query.user){//根据当前登录用户查询
        data = await Article.findByUser(ctx.query.user)
    }
    if(data == null){
        data = await Article.randFee()
    }
    if(data == null){
        data = await Article.rand()
    }
    return data
})

router.get('/banners', async(ctx)=>{
    let page = ctx.query.page || 1
    let datas = []
    let feeData = await Article.bannersByFee(page)
    datas = feeData.rows
    let notFee = []
    if(datas.length < 10){
        notFee = await Article.bannersByNotFee()
        if(notFee.rows.length >= 10 - datas.length){
            datas = datas.concat(notFee.rows.slice(0, 10 - datas.length))
        }else{
            datas = datas.concat(notFee.rows.slice(0, notFee.rows.length))
        }
    }
    return {
        count : Math.ceil(feeData.count / 10),
        data : datas
    };
})

router.post('/submit', async(ctx)=>{
    let form = ctx.request.body
    let article = await Article.save({ ...form, status : 0})
    let order = {
        user : form.user,
        article : article.id,
        order_no : Date.now() + RndNum(5) + '',
        pay_price : ctx.request.body.fee,
        pay_status : 0,
        nonceStr : randomString(32),
        timeStamp : formatDateTime(),
        transaction_id : '',
    }
    await Order.save(order)
    let back = await weixin_unifiedorder(order, getClientIp(ctx.req));
    console.log(back)
    return { pay : back, article : article }
})

router.post('/submitFree', async(ctx)=>{
    let form = ctx.request.body
    return await Article.save({ ...form, status : 1})
})

router.post('/payback', async(ctx)=>{
    let data = ctx.request.body
    ctx.res.setHeader('Content-Type', 'application/xml')
    try {
        if(data.xml.result_code == 'SUCCESS'){
            let order = await Order.get(data.xml.out_trade_no)
            if(order == null){
                ctx.res.end(`<xml>${json2xml.parse({return_code : 'FAIL', return_msg:'Order不存在'})}</xml>`)
                return
            }
            if(order.pay_status == 1){
                ctx.res.end(`<xml>${json2xml.parse({return_code : 'SUCCESS', return_msg:'OK'})}</xml>`)
                return
            }
            if(parseInt(order.pay_price * 100) == parseInt(data.xml.total_fee)){
                order.pay_status = 1
                order.transaction_id = data.xml.transaction_id
                let article = await Article.get(order.article)
                article.status = 1
                order.save()
                article.save()
                ctx.res.end(`<xml>${json2xml.parse({return_code : 'SUCCESS', return_msg:'OK'})}</xml>`)
                return
            }else{
                ctx.res.end(`<xml>${json2xml.parse({return_code : 'FAIL', return_msg:'支付价格和订单价格不一致'})}</xml>`)
                return
            }
        }else{
            ctx.res.end(`<xml>${json2xml.parse({return_code : 'FAIL', return_msg:'支付失败'})}</xml>`)
            return
        }
    } catch (error) {
        console.log(error)
        ctx.res.end(`<xml>${json2xml.parse({return_code : 'FAIL', return_msg:'未知错误'})}</xml>`)
        return
    }
})

const RndNum = (n) => {
    var rnd="";
    for(var i=0;i<n;i++)
        rnd+=Math.floor(Math.random()*10);
    return rnd;
}

function getClientIp(req) {
    return req.headers['x-forwarded-for'] ||
    req.connection.remoteAddress ||
    req.socket.remoteAddress ||
    req.connection.socket.remoteAddress;
}

function randomString(len) {
    let charSet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    let randomString = '';
    for (let i = 0; i < len; i++) {
        let randomPoz = Math.floor(Math.random() * charSet.length);
        randomString += charSet.substring(randomPoz,randomPoz+1);
    }
    return randomString;
}

function formatDateTime() {
    var date = new Date();
    var y = date.getFullYear();
    var m = date.getMonth() + 1;
    m = m < 10 ? ('0' + m) : m;
    var d = date.getDate();
    d = d < 10 ? ('0' + d) : d;
    var h = date.getHours();
    h = h < 10 ? ('0' + h) : h;
    var minute = date.getMinutes();
    var second = date.getSeconds();
    minute = minute < 10 ? ('0' + minute) : minute;
    second = second < 10 ? ('0' + second) : second;
    return '' + y + m + d + h + minute + second;
}

function weixin_unifiedorder(order, spbill_create_ip){
    let postData = {
        appid : CONFIG.APPID,
        attach : '祝福接力',
        body : '祝福接力-祝福上墙',
        mch_id : CONFIG.MATCHID,
        nonce_str : order.nonceStr,
        notify_url : CONFIG.SERVER + '/api/order/payback',
        openid : order.user,
        out_trade_no : order.order_no,
        spbill_create_ip : spbill_create_ip,
        total_fee : parseInt(order.pay_price * 100),
        trade_type : 'JSAPI',
    }
    postData.sign = paysign(postData)
    let formData = json2xml.parse(postData)
    return new Promise((resolve, reject) =>
        request.post('https://api.mch.weixin.qq.com/pay/unifiedorder', { body : `<xml>${formData}</xml>` }, function (err, response, body) {
            if (!err && response.statusCode == 200) {
                let data = xml2json.parse(body)
                if(data.xml.return_code != 'SUCCESS'){
                    reject(data.xml.return_msg);
                }else{
                    let payForm = {
                        appId : postData.appid,
                        timeStamp : order.timeStamp,
                        nonceStr : postData.nonce_str,
                        package : `prepay_id=${data.xml.prepay_id}`,
                        signType : 'MD5',
                    }
                    payForm.paySign = paysign(payForm)
                    resolve(payForm);
                }
            }else{
                reject(err);
            }
        })
    );
}

function paysign(postData) {
    let keys = Object.keys(postData).sort()
    let signStr = ''
    keys.forEach(k=>{ signStr += '&' + k + '=' + postData[k] })
    signStr = signStr.substr(1)  + '&key='+ CONFIG.MATCHKEY
    return crypto.createHash('md5').update(signStr,'utf8').digest('hex');
}


export default router